import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 姚东名
 * Date: 2024-06-04
 * Time: 21:10
 */
class Solution {
    //1.
    public int firstUniqChar(String s) {
        int[] count = new int[26];//这个数组拿来计数：字符出现的次数
        for(int i = 0; i < s.length(); i++) {
            //从字符串中拿出字符：
            char ch = s.charAt(i);//length
            //放在计数的数组中
            count[ch - 'a'] ++;
        }
        //计数完重新遍历一遍字符串，找到它的第一个不重复的字符
        for(int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if(count[ch - 'a'] == 1) {
                return i;
            }
        }
        return -1;
    }
    //3.
    public boolean isPalindrome(String s) {
        //所有大写字符转换为小写字符:
        s = s.toLowerCase();
        //开始判断：定义两个索引：一个从左边开始， 一个从右边开始，进行对比
        int left = 0;
        int right = s.length() - 1;
        //开始对比：
        while(left < right) {
            //遇到非字母和非数字就跳过，不进行比较
            while(left < right && !isNumberAndCharacter(s.charAt(left))) {
                left++;
            }
            while(left < right && !isNumberAndCharacter(s.charAt(right))) {
                right--;
            }
            //走到这，证明字符都是字母，可以进行对比
            if(s.charAt(left) == s.charAt(right)) {
                left++;
                right--;
                //对比完，就往下走
            }else {
                //不相同，说明不是回文串
                return false;
            }
        }
        //走到这，证明是回文串
        return true;
    }
    //字母和数字都属于字母数字字符。 -> 假如是非字母和非数字就跳过，不进行比较
    private boolean isNumberAndCharacter(char ch) {
        //用isDigit() : 判断字符是否为数字
        //用isLetter() : 判断字符是否为字母
        if(Character.isDigit(ch) || Character.isLetter(ch)) {
            return true;
        }else {
            return false;
        }
    }
}
public class Test {
    public static void main(String[] args) {
        //1.给定一个字符串 s ，找到 它的第一个不重复的字符，并返回它的索引 。如果不存在，则返回 -1 。
        String s = "abcdef";
        System.out.println(s.substring(1));
        //2.输出一个整数，表示输入字符串最后一个单词的长度。描述：输入：hello nowcoder 输出：8

        //3.如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后，短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
        //字母和数字都属于字母数字字符。
        char ch = 'a';
        Character.isDigit(ch);
    }
    //2.
    public static void main17(String[] args) {
        //方法1：使用split方法 -》 切割字符串
        /*Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        //使用split切割字符串，装在新的数组中
        String[] ss = s.split(" ");
        //取出最后一个索引的内容
        int len = ss[ss.length - 1].length();
        System.out.println(len);
        */

        //方法2：使用lastIndexOf() 和 substring()
        //lastIndexOf() : 从字符串的后面开始找： " ",找到就返回索引，否则就返回-1
        //substring(int beginIndex) : 从beginIndex开始发生截断
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        //找最后一个空格后面的字符串
        int index = s.lastIndexOf(" ");
        //从index索引开始发生截断 -> 得到index+1后面的字符串
        int len = s.substring(index + 1).length();
        System.out.println(len);
    }
    public static void main16(String[] args) {
        long start = System.currentTimeMillis();
        String s = "";
        for(int i = 0; i < 10000; ++i){
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);//235
        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 10000; ++i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);//0
        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);//0
    }

    public static void main15(String[] args) {
        /**字符串修改：
         * 注意：尽量避免直接对String类型对象进行修改，因为String类是不能修改的，所有的修改都会创建新对象，效率非常低下。
         * 不推荐使用，中间创建了好多临时变量：
         * 避免对String的直接需求，如果要修改建议使用StringBuffer或者StringBuilder
         */
        String s = "hello";
        s += " world";
        System.out.println(s);
        /**
         * 由于String的不可更改特性，为了方便字符串的修改，Java又提供StringBuffer和StringBuilder类，这两个类与String类大部分功能相同
         */
        StringBuilder stringBuilder = new StringBuilder("abcdef");
        //1.public StringBuilder insert(int offset, String str) -> 从offset索引开始，插入str
        stringBuilder.insert(3, "haha");
        System.out.println(stringBuilder);//abchahadef
        System.out.println("================");
        //2.public StringBuilder reverse() -> 逆置字符串
        stringBuilder.reverse();
        System.out.println(stringBuilder);
        System.out.println("================");
        stringBuilder.reverse();
        System.out.println(stringBuilder);
        /**
         * String、StringBuffer、StringBuilder的区别
         * 1.String的内容不可修改，StringBuffer和StringBuilder的内容可以修改
         * 2.StringBuffer与StringBuilder大部分功能相似的
         * 3.StringBuffer采用同步处理(用synchronized关键字修饰)，属于线程安全操作（多线程）
         *   StringBuilder未采用同步处理，属于线程不安全操作（单线程）
         */
    }
    public static void main14(String[] args) {
        /**字符串的不可变性：String类是一种不可变对象，字符串中的内容是不可以改变的，字符串不可以被修改，是因为
         * private final char value[]; —>
         * 1. value[] 被private限定符修饰，只能在同一个类才能使用，不同类、不同包都不能使用
         * 2.String类被final修饰，表示该类不能被继承
         * 3.value被final修饰，表明value自身的值不能改变，即不能引用其他字符数组，但是其引用空间中的内容可以修改。
         */
         String s = "abcd";
        final char[] array = {'a', 'b', 'c'};
        array[0] = 'g';
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
        //但是array被final所修饰，证明array这个引用不能发生改变
        //error: array = new char[10];
    }
    public static void main13(String[] args) {
        //字符串截取：
        //1.String subString(int beginIndex) -> 从指定索引截取到结尾
        String s = "abcdef";
        String s2 = s.substring(2);
        System.out.println(s2);//cdef
        System.out.println("================");
        //2.String subString(int beginIndex, int endIndex) -> 截取部分内容
        String str = "aaabbbccc";
        System.out.println(str.substring(3, 6));//[)：左边包括，右边不包括//bbb
    }
    public static void main12(String[] args) {
        //去掉字符串中的左右空格,保留中间空格 -> String trim()
        String s = "  aa  aa  sss cc c c c c    ";
        System.out.println(s);
        System.out.println("================");
        System.out.println(s.trim());//只会去除 左右两边的空格
    }
    public static void main11(String[] args) {
        /**注意事项：
         * 1.字符"|"、"*"、"+"都得加上转义字符，前面加上"\\"
         * 2.而如果是"\"，那么就得写成"\\\\"
         * 3.如果一个字符串中有多个分隔符，可以用"|"作为连字符
         */

        //字符串拆分：String[] split(String regex) :将字符串全部拆分
        String s = "name = zhangsan&age = 10";
        //返回值是数组：String[]
        String[] strings = s.split("&");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
        /*System.out.println("================");
        String s1 = "name=zhangsan&age=10";
        //返回值  是数组
        String[] strings1 = s.split("=|&");
        for (int i = 0; i < strings1.length; i++) {
            System.out.println(strings[i]);
        }*/
        System.out.println("================");
        //String[] split(String regex, int limit) : 将字符串以指定格式，拆分为limit组
        String str = "love you, mom. see you tomorrow";
        //String str = "hello world hello bit" ;
        String[] result = str.split(" ", 4);
        for (int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }
    public static void main10(String[] args) {
        //使用一个指定的新的字符串替换掉已有的字符串数据 -> 关键字：replace
        String s = "aaabbbccc";
        String tmp = s.replace('a', 'k');
        System.out.println(tmp);
        //也可以替换字符串 -> 例如："ab"
        System.out.println(s.replace("ab", "mmm"));
        System.out.println("==========");
        tmp = s.replaceAll("ab","ooo");
        System.out.println(tmp);
    }
    public static void main9(String[] args) {
        //字符串转数组
        String s1 = "hello";
        char[] array = s1.toCharArray();
        for (int i = 0; i < s1.length(); i++) {
            System.out.print(array[i] + " ");//h e l l o
        }
        System.out.println();
        System.out.println("================");
        //数组转字符串
        String s2 = new String(array);//hello
        System.out.println(s2);
        System.out.println("================");
        //格式化：
        String s3 = String.format("%d-%d-%d", 2024, 06, 04);
        System.out.println(s3);
        System.out.println("================");
    }
    public static void main8(String[] args) {
        //大小写转换：关键字：小写转大写toUpperCase() 与 大写转小写toLowerCase()
        String s = "hello";
        System.out.println(s.toUpperCase());
        System.out.println("================");
        String s2 = "ASCII";
        System.out.println(s.toLowerCase());
        //注意：toUpperCase 和 toLowerCase不能把非字母的字符串转换
        String s3 = "haha哈哈";
        System.out.println(s3.toUpperCase());//HAHA哈哈
    }
    public static void main7(String[] args) {
        //数值和字符串之间的转化
        String s1 = String.valueOf(1234);
        //1.数值转换为字符串
        System.out.println(s1 + 1);//12341
        String s2 = String.valueOf(12.3);
        System.out.println(s2 + 1);//无法相加，因为s2已经变成了字符串了
        String s3 = String.valueOf(true);
        System.out.println(s3);
        System.out.println("================");
        //2.字符串转换为数值
        int data1 = Integer.parseInt("1234");
        System.out.println(data1 + 1);//1235 ->证明把"1234"转换为与数值 数值1234 -> 数值与数值之间才能相加
        double data2 = Double.parseDouble("3.14");
        System.out.println(data2 + 1);
        System.out.println(data2);
    }
    public static void main6(String[] args) {
        //3.字符串查找：lastIndexOf与indexOf情况差不多，唯一区别是：lastIndexOf()是从字符串的后面开始找
        String s = "aababcabcd";
        //从后往前找，返回a第一次出现的位置，没有就返回-1
        int index = s.lastIndexOf('a');
        System.out.println(index);//6
        System.out.println("================");
        //也是可以找字符串的
        int index1 = s.lastIndexOf("abcd");
        System.out.println(index1);//6
        System.out.println("================");
        //也可在指定位置fromIndex开始找
        int index2 = s.lastIndexOf("abc", 6);//3
        System.out.println(index2);
    }
    public static void main5(String[] args) {
        //2.字符串查找：indexOf不仅可以找字符串的字符,例如 -> 'a'，也可找字符串，例如 -> "abc"
        String s = "aababcabcd";
        //规则：返回s第一次出现的位置，没有就返回-1，毕竟索引没有负数，代表没有找到
        int index1 = s.indexOf('b');//位置默认从零位置开始找
        System.out.println(index1);
        System.out.println("================");
        //规则：从fromIndex位置开始找，返回s第一次出现的位置，没有就返回-1
        int index2 = s.indexOf("abc", 3);
        System.out.println(index2);
    }
    public static void main4(String[] args) {
        //1.字符串查找:
        String s = "aababcabcd";
        //1.charAt()：返回index位置上字符，如果index为负数或者越界，抛出
        //IndexOutOfBoundsException异常
        System.out.println(s.charAt(5));//括号里面的需要的是一个索引
        //单独拿到s字符串的每个元素
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            System.out.print(ch + " ");
        }
        //与数组求长度不一样，字符串求字符串的长度是调用 s.length() 这是一个方法，而数组是没有括号的
        int[] array = {1, 2, 3, 4, 5};
        System.out.println(array.length);//这是一个关键字
    }

    public static void main3(String[] args) {
        String s1 = new String("abcd");
        String s2 = new String("abcD");
        /**比较字符串的大小：
         * 1.根据对应字母的ASCII码来比较
         * 2.对应字符 无法比较出来谁大谁小，此时就比较字符串的长度
         */
        System.out.println(s1.compareTo(s2));//32
        //忽略字母的大小写，因为同一个字母的大小写的ASCII码对应大小是不一样的 -> compareToIgnoreCase可忽略大小写
        System.out.println(s1.compareToIgnoreCase(s2));//0

    }

    public static void main2(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        String s3 = s1;
        System.out.println("================");
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s3);//true
        System.out.println(s3 == s2);//false
        System.out.println("================");
        //1.比较的是里面的内容：s1与s2的内容都是hello，s3与s1是一样的，指向的都是hello
        //2.先检测this(谁调用谁就是this)和anObject(传过去的形参)是否为同一个对象，如果是则返回true,否则返回false
        System.out.println(s1.equals(s2));//true
        System.out.println(s1.equals(s3));//true
        System.out.println(s2.equals(s3));//true
    }

    public static void main1(String[] args) {
        String str1 = "hello";
        String str2 = new String("world");
        char[] value = {'a', 'b', 'c'};
        String str3 = new String(value);
        String str4 = str1;//把str1引用赋值给str4了

        System.out.println(str1);//hello
        System.out.println(str2);//world
        System.out.println(str3);//abc
        System.out.println(str4);//hello
    }
}
